package com.motu.monstercity.server.game.logichandler;

import com.google.protobuf.InvalidProtocolBufferException;
import com.motu.monstercity.module.common.iap.IapGiftPush;
import com.motu.monstercity.module.common.network.RequestParam;
import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.protocol.Common.PBUserSnatchTeam;
import com.motu.monstercity.protocol.CsGameFight.*;
import com.motu.monstercity.server.game.base.AllParam;
import com.motu.monstercity.server.game.base.CommonUtils;
import com.motu.monstercity.server.game.base.LockKey;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.act.ActTopRanking;
import com.motu.monstercity.server.game.commondata.bag.ItemId;
import com.motu.monstercity.server.game.commondata.fight.*;
import com.motu.monstercity.server.game.commondata.maintask.MainTaskConstant;
import com.motu.monstercity.server.game.commondata.rank.RankConstant;
import com.motu.monstercity.server.game.commondata.rank.RankReward;
import com.motu.monstercity.server.game.commondata.skill.SkillConstant;
import com.motu.monstercity.server.game.commondata.system.SystemConstant;
import com.motu.monstercity.server.game.log.LogType;
import com.motu.monstercity.server.game.log.ThinkingDataManager;
import com.motu.monstercity.server.game.logic.*;
import com.motu.monstercity.server.game.timedtask.TimeTaskCmd;
import com.motu.monstercity.server.game.timedtask.TimedTaskManager;
import com.motu.monstercity.server.game.userdata.*;
import com.motu.vertx.module.utility.main.MainService;
import com.motu.vertx.module.utility.redis.RedisTools;
import com.motu.vertx.module.utility.toolset.ErrorWord;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.Future;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.shareddata.Lock;
import io.vertx.ext.auth.User;

import java.util.ArrayList;
import java.util.List;

public class FightHandler {
    // CMD_GAME_FIGHT_STAGE_FIGHT = 71001;// 主线关卡战斗
    public static Object CMD_GAME_FIGHT_STAGE_FIGHT(RequestParam clientParam) throws Exception {
        CSGameFightStageFightRequest request = CSGameFightStageFightRequest.parseFrom(clientParam.getData());
        CSGameFightStageFightResponse.Builder response = CSGameFightStageFightResponse.newBuilder();
        long userId = clientParam.getUserId();

        UserStage userStage = FightManager.getUserStage(userId);
        int mapId = userStage.getMapId();
        int stageId = userStage.getStageId();
        int areaId = userStage.getUnlockAreaId();
        Stage stage = FightManager.getStage(mapId, stageId);
        StageArea stageArea = FightManager.getStageArea(areaId);
        if (stage == null || stageArea == null) {
            return ErrorWord.NOT_DATA;
        }

        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserPower userPower = GameUser.getUserPower(userId);
        int itemId = ItemId.GOLD;// 金币鼓舞
        long subNum = 0L;// 需要消耗的金币
        if (stage.isPowerStage()) {// 战力关卡
            long powerStage = FightManager.takeStagePowerInspire(userId, userStage);// 鼓舞后的总战力
            if (powerStage < FightManager.countPowerStageForces(userId, stage)) {
                return ErrorWord.TIMES_LACK;// 战力不足
            }
        } else {
            subNum = FightManager.countStageTotalGold(userInfo, stage, userPower);// 这个关卡总的需要消耗的金币数量
            long userItemNum = BagManager.getUserItemNum(userInfo, itemId);
            if (userItemNum < subNum) {
                return ErrorWord.ITEM_LACK;// 道具不足
            }
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        if (stage.isGoldStage()) {
            RewardManager.subReward(userInfo, itemId, subNum, pbUserData, LogType.FIGHT_STAGE_FIGHT);// 普通关卡扣除金币
            JsonArray nodeRewardArray = userStage.getNodeRewardArray();// 小节奖励列表
            JsonArray jsonArray = FightManager.countStageReward(stage);// 这个关卡获得的小节奖励
            for (int i=0;i<jsonArray.size();i++) {
                nodeRewardArray.add(jsonArray.getLong(i));
            }
            userStage.putNodeReward(nodeRewardArray.toString());
            userStage.putStageId(stageId + 1);

        } else if (stage.isBossStage()) {// 这一章的最后一关卡
            if (FightManager.isAreaEndMap(mapId, userStage.getUnlockAreaId())) {// 判断该章节id 是否 该区域的最后一章节
                int nextAreaId = userStage.getUnlockAreaId() + 1;
                userStage.putUnlockAreaId(nextAreaId);// 解锁下一区块
            }
            userStage.putMapId(mapId + 1);
            userStage.putStageId(1);

            GameIapManager.checkTriggerIapGiftPush(userInfo, IapGiftPush.TYPE_STAGE, userStage.getMapId());

            userStage.putInspireNum(0);
            userStage.putInspireItemNum(0);
            RewardManager.addReward(userInfo, CommonUtils.takeReawrdItemFromStr(stage.getReward()), pbUserData, LogType.FIGHT_STAGE_FIGHT);
            MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_35, 1);// 更新主线任务,成就,日常任务的进度
            RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_35, 1);
        }

        if (!userStage.isGuardRewardOpen()) {// 未解锁时，解锁围墙卫兵挂机奖励功能
            FightManager.unlockStageGuardReward(pbUserData, userInfo, userStage);//
        }

        EventManager.triggerNormalEvent(userInfo, stage, pbUserData);
        userStage.update();
        long stageProgress = userStage.getStageProgress();
        RankActManager.addUserrank(userInfo.getServerId(), ActTopRanking.RANK_TYPE_STAGE, userInfo, stageProgress, false);
        RankActManager.addUserCrossRank(userInfo, userInfo.getServerId(), ActTopRanking.RANK_TYPE_STAGE, stageProgress, false);
        ProtoDataUtils.updatePBUserData(pbUserData, userStage);
        MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_112, 1);// 更新主线任务,成就,日常任务的进度
        RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_112, 1);
        userInfo.putStageKey(FightManager.getStageKey(mapId, stageId));
        userInfo.update();
        // 上报数数
        ThinkingDataManager.pushUserStageFightEvent(userInfo, 1, FightManager.getStageKey(mapId, stageId), true, userPower);

        return response;
    }


    // CMD_GAME_FIGHT_STAGE_GET_STAGE_REWARD = 71051;// 主线关卡领取关卡各个小节奖励
    public static Object CMD_GAME_FIGHT_STAGE_GET_STAGE_REWARD(RequestParam clientParam) throws Exception {
        CSGameFightStageGetStageRewardRequest request = CSGameFightStageGetStageRewardRequest.parseFrom(clientParam.getData());
        CSGameFightStageGetStageRewardResponse.Builder response = CSGameFightStageGetStageRewardResponse.newBuilder();
        long userId = clientParam.getUserId();

        UserStage userStage = FightManager.getUserStage(userId);
        int newNodeNum = request.getNodeNum();
        int totalNodeNum = FightManager.countNodeNum(userStage.getMapId());// 总的有多少小节
        if (newNodeNum <= userStage.getNodeNum() || newNodeNum > totalNodeNum) {
            //return ErrorWord.REPEATED_OPERATION;// 已领取过了
            return response;
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserInfo userInfo = GameUser.getUserInfo(userId);
        int itemId = ItemId.PARTNER_EXP;// 获得经验
        long total = 0L;//
        JsonArray jsonArray = userStage.getNodeRewardArray();// 小节奖励列表
        if (jsonArray.size() < newNodeNum) {
            //return ErrorWord.WRONG_STATUS;// 未打过
            return response;
        }
        for (int i=userStage.getNodeNum();i<newNodeNum;i++) {
            total += jsonArray.getLong(i);
        }

        RewardManager.addReward(userInfo, itemId, total, pbUserData, LogType.FIGHT_STAGE_FIGHT);
        if (newNodeNum == totalNodeNum) {// 全部领取完
            userStage.putNodeNum(0);
            userStage.putNodeReward("");
        } else {
            userStage.putNodeNum(newNodeNum);
        }
        userStage.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userStage);

        return response;
    }


    // CMD_GAME_FIGHT_STAGE_INSPIRE = 71002;// 主线关卡战斗鼓舞
    public static Object CMD_GAME_FIGHT_STAGE_INSPIRE(RequestParam clientParam) throws Exception {
        CSGameFightStageInspireRequest request = CSGameFightStageInspireRequest.parseFrom(clientParam.getData());
        CSGameFightStageInspireResponse.Builder response = CSGameFightStageInspireResponse.newBuilder();
        long userId = clientParam.getUserId();

        int num = request.getNum();// 金币鼓舞次数
        int num2 = request.getNum2();// 道具鼓舞次数
        UserStage userStage = FightManager.getUserStage(userId);
        int mapId = userStage.getMapId();
        int stageId = userStage.getStageId();
        Stage stage = FightManager.getStage(mapId, stageId);
        if (stage == null || !stage.isPowerStage()) {
            return ErrorWord.NOT_DATA;// 不是战力关卡,不能鼓舞
        }

        int inspireNum = userStage.getInspireNum();// 金币鼓舞次数
        int maxNum = AllParam.INSPIRE_LIMIT[0];// 金币鼓舞次数上限
        int itemId = ItemId.GOLD;// 金币鼓舞
        long subNum = FightManager.takeStageInspireGoldNum(stage, inspireNum);// 需要消耗的金币数量

        int inspireNum2 = userStage.getInspireItemNum();// 道具鼓舞次数
        int maxNum2 = AllParam.INSPIRE_LIMIT[1];// 道具鼓舞次数上限
        int itemId2 = AllParam.INSPIRE_ITEM_COST[0];// 到家鼓舞
        long subNum2 = AllParam.INSPIRE_ITEM_COST[1];// 需要消耗的道具数量

        if (inspireNum + num > maxNum || inspireNum2 + num2 > maxNum2) {
            return ErrorWord.ALREADY_MAX;//  次数达到上限
        }
        UserInfo userInfo = GameUser.getUserInfo(userId);
        long userItemNum = BagManager.getUserItemNum(userInfo, itemId);
        long userItemNum2 = BagManager.getUserItemNum(userInfo, itemId2);
        if (num > 0 && userItemNum < subNum) {
            return ErrorWord.ITEM_LACK;// 道具数量不足
        }
        if (num2 > 0 && userItemNum2 < subNum2) {
            return ErrorWord.ITEM_LACK;// 道具数量不足
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        if (num > 0) {
            RewardManager.subReward(userInfo, itemId, subNum, pbUserData, LogType.FIGHT_STAGE_INSPIRE);
            userStage.addInspireNum(num);
        }
        if (num2 > 0) {
            RewardManager.subReward(userInfo, itemId2, subNum2, pbUserData, LogType.FIGHT_STAGE_INSPIRE);
            userStage.addInspireItemNum(num2);
        }
        userStage.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userStage);

        return response;
    }

    // CMD_GAME_FIGHT_STAGE_GET_AREA_REWARD = 71003;// 主线关卡领取区域探索奖励
    public static Object CMD_GAME_FIGHT_STAGE_GET_AREA_REWARD(RequestParam clientParam) throws Exception {
        CSGameFightStageGetAreaRewardRequest request = CSGameFightStageGetAreaRewardRequest.parseFrom(clientParam.getData());
        CSGameFightStageGetAreaRewardResponse.Builder response = CSGameFightStageGetAreaRewardResponse.newBuilder();
        long userId = clientParam.getUserId();

        int areaId = request.getAreaId();
        StageArea stageArea = FightManager.getStageArea(areaId);
        if (stageArea == null) {
            return ErrorWord.NOT_DATA;
        }
        UserStage userStage = FightManager.getUserStage(userId);
        if (areaId >= userStage.getUnlockAreaId()) {
            return ErrorWord.WRONG_STATUS;// 该区块未全部清理
        }

        JsonArray jsonArray = userStage.getAreaRewardArray();
        if (Tool.isInList(jsonArray, areaId)) {
            return ErrorWord.REPEATED_OPERATION;// 已经领取过了
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserInfo userInfo = GameUser.getUserInfo(userId);
        RewardManager.addReward(userInfo, CommonUtils.takeReawrdItemFromStr(stageArea.getReward()), pbUserData, LogType.FIGHT_STAGE_AREA_REWARD, areaId);
        jsonArray.add(areaId);
        userStage.putAreaReward(jsonArray.toString());
        userStage.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userStage);
        // 检测礼包推送
        GameIapManager.checkTriggerIapGiftPush(userInfo, IapGiftPush.TYPE_STAGE, userStage.getMapId());

        return response;
    }


    // CMD_GAME_FIGHT_STAGE_GUARD_REWARD_PREVIEW = 71008;// 卫兵挂机奖励预览，进行结算
    public static Object CMD_GAME_FIGHT_STAGE_GUARD_REWARD_PREVIEW(RequestParam clientParam) throws Exception {
        CSGameFightStageGuardRewardPreviewRequest request = CSGameFightStageGuardRewardPreviewRequest.parseFrom(clientParam.getData());
        CSGameFightStageGuardRewardPreviewResponse.Builder response = CSGameFightStageGuardRewardPreviewResponse.newBuilder();
        long userId = clientParam.getUserId();

        UserStage userStage = FightManager.getUserStage(userId);
        if (!userStage.isGuardRewardOpen()) {
            return ErrorWord.WRONG_STATUS;//  卫兵挂机奖励功能未开启
        }

        Stage stage = userStage.takeCompleteStage();// 当前已完成的最大关卡
        if (stage == null) {
            return ErrorWord.NOT_DATA;
        }

        // 执行逻辑
        UserInfo userInfo = GameUser.getUserInfo(userId);
        PBUserData.Builder pbUserData = response.getUserBuilder();
        if (FightManager.closeStageGuardReward(userInfo, userStage)) {// 结算卫兵的挂机奖励
            userStage.update();
            ProtoDataUtils.updatePBUserData(pbUserData, userStage);
        }

        return response;
    }

    // CMD_GAME_FIGHT_STAGE_GUARD_REWARD_GET = 71009;// 卫兵挂机奖励预览，领取
    public static Object CMD_GAME_FIGHT_STAGE_GUARD_REWARD_GET(RequestParam clientParam) throws Exception {
        CSGameFightStageGuardRewardGetRequest request = CSGameFightStageGuardRewardGetRequest.parseFrom(clientParam.getData());
        CSGameFightStageGuardRewardGetResponse.Builder response = CSGameFightStageGuardRewardGetResponse.newBuilder();
        long userId = clientParam.getUserId();

        UserStage userStage = FightManager.getUserStage(userId);
        if (!userStage.isGuardRewardOpen()) {
            return ErrorWord.WRONG_STATUS;//  卫兵挂机奖励功能未开启
        }

        Stage stage = userStage.takeCompleteStage();// 当前已完成的最大关卡
        if (stage == null) {
            return ErrorWord.NOT_DATA;
        }

        // 执行逻辑
        UserInfo userInfo = GameUser.getUserInfo(userId);
        PBUserData.Builder pbUserData = response.getUserBuilder();
        FightManager.closeStageGuardReward(userInfo, userStage);
        List<RewardItem> rewardItemList = MailManager.takeRewardItem(userStage.getGuardReward());
        RewardManager.addReward(userInfo, rewardItemList, pbUserData, LogType.FIGHT_STAGE_GUARD_REWARD);

        long curTime = TimeUtils.getCurTime();// 当前时间的分钟数
        userStage.putGuardRewardTime(curTime);
        if (FightManager.getGuardTimeMax(userInfo.getId()) <= userStage.getGuardCloseTime()) {// 达到时间上限, 从当前开始计时
            userStage.putGuardRewardRandomTime(curTime);
        }

        userStage.putGuardReward("");
        userStage.putGuardRewardLastTime(curTime);
        userStage.putGuardCloseTime(0);// 清空记录
        userStage.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userStage);

        return response;
    }


    // CMD_GAME_FIGHT_STAGE_GUARD_REWARD_GET_QUICK = 71010;// 卫兵挂机奖励预览，快速额外领取，额外消耗钻石
    public static Object CMD_GAME_FIGHT_STAGE_GUARD_REWARD_GET_QUICK(RequestParam clientParam) throws Exception {
        CSGameFightStageGuardRewardGetQuickRequest request = CSGameFightStageGuardRewardGetQuickRequest.parseFrom(clientParam.getData());
        CSGameFightStageGuardRewardGetQuickResponse.Builder response = CSGameFightStageGuardRewardGetQuickResponse.newBuilder();
        long userId = clientParam.getUserId();

        UserStage userStage = FightManager.getUserStage(userId);
        if (!userStage.isGuardRewardOpen()) {
            return ErrorWord.WRONG_STATUS;//  卫兵挂机奖励功能未开启
        }

        Stage stage = userStage.takeCompleteStage();// 当前已完成的最大关卡
        if (stage == null) {
            return ErrorWord.NOT_DATA;
        }

        UserInfo userInfo = GameUser.getUserInfo(userId);
        if (userStage.getGuardQuickNum() >= FightManager.getGuardQuickMaxNum(userId)) {
            return ErrorWord.ALREADY_MAX;// 次数达到上限
        }

        int itemId = ItemId.DIAMOND;// 额外领取，需要消耗钻石
        int subNum = FightManager.getGuardQuickCostNum(userStage);
        if (BagManager.getUserItemNum(userInfo, itemId) < subNum) {
            return ErrorWord.ITEM_LACK;// 钻石不足
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        RewardManager.subReward(userInfo, itemId, subNum, pbUserData, LogType.FIGHT_STAGE_GUARD_REWARD_QUICK, userStage.getGuardQuickNum() + 1);

        int num = AllParam.GUARD_QUICK_TIME;// 表示每次快速领取的时间120分钟 普通奖励120份，1分钟1份
        int randomNum = AllParam.GUARD_QUICK_TIME / AllParam.GUARD_BOX_TIME;// 随机奖励，没5分钟1份

        List<RewardItem> rewardItemList = FightManager.getGuardRandomReward(userStage, randomNum);
        rewardItemList.add(new RewardItem(ItemId.GOLD, stage.getGuardGoldNum() * num));
        rewardItemList.add(new RewardItem(ItemId.PARTNER_EXP, stage.getGuardExpNum() * num));
        rewardItemList.add(new RewardItem(ItemId.USER_REPU, stage.getGuardCityExpNum() * num));
        RewardManager.addReward(userInfo, rewardItemList, pbUserData, LogType.FIGHT_STAGE_GUARD_REWARD_QUICK);

        userStage.addGuardQuickNum(1);// 次数+1
        userStage.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userStage);

        return response;
    }

    // CMD_GAME_FIGHT_MONSTER_TIDE_UNLOCK = 71004;// 解锁兽潮模块的用户数据
    public static Object CMD_GAME_FIGHT_MONSTER_TIDE_UNLOCK(RequestParam clientParam) throws Exception {
        CSGameFightMonsterTideFightRequest request = CSGameFightMonsterTideFightRequest.parseFrom(clientParam.getData());
        CSGameFightMonsterTideFightResponse.Builder response = CSGameFightMonsterTideFightResponse.newBuilder();
        long userId = clientParam.getUserId();

        UserMonsterTideInfo userMonsterTideInfo = FightManager.getUserMonsterTiedInfo(userId);
        if (userMonsterTideInfo == null) {// 解锁兽潮
            userMonsterTideInfo = FightManager.unlockMonsterTide(userId);
            PBUserData.Builder pbUserData = response.getUserBuilder();
            ProtoDataUtils.updatePBUserData(pbUserData, userMonsterTideInfo, true);
        }
        return response;
    }

    // CMD_GAME_FIGHT_MONSTER_TIDE_FIGHT = 71005;// 兽潮来袭的触发战斗,生成战报,获得奖励
    public static Object CMD_GAME_FIGHT_MONSTER_TIDE_FIGHT(RequestParam clientParam) throws Exception {
        CSGameFightMonsterTideFightRequest request = CSGameFightMonsterTideFightRequest.parseFrom(clientParam.getData());
        CSGameFightMonsterTideFightResponse.Builder response = CSGameFightMonsterTideFightResponse.newBuilder();
        long userId = clientParam.getUserId();

        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserMonsterTideInfo userMonsterTideInfo = FightManager.getUserMonsterTiedInfo(userId);

        if (userMonsterTideInfo == null || userMonsterTideInfo.getNextMonsterTideId() == 0 || userMonsterTideInfo.getNextTime() == 0) {
            return ErrorWord.WRONG_STATUS;
        }

        PBUserData.Builder pbUserData = response.getUserBuilder();
        pbUserData.getSystemBuilder().setSvrTime(TimeUtils.getCurTime());// 告诉客户端同步时间

        if (TimeUtils.getCurTime() >= userMonsterTideInfo.getMinTime()) {// 当前时间过了最小时间才允许战斗
            UserPower userPower = GameUser.getUserPower(userId);
            UserAffair userAffair = GameUser.getUserAffair(userId);
            FightManager.monsterTideFight(pbUserData, userInfo, userPower, userMonsterTideInfo, userAffair);
        }

        return response;
    }

    // CMD_GAME_FIGHT_MONSTER_TIDE_FIGHT_ITEM = 71007;// 花费道具额外触发兽潮,生成战报,获得奖励
    public static Object CMD_GAME_FIGHT_MONSTER_TIDE_FIGHT_ITEM(RequestParam clientParam) throws Exception {
        CSGameFightMonsterTideFightItemRequest request = CSGameFightMonsterTideFightItemRequest.parseFrom(clientParam.getData());
        CSGameFightMonsterTideFightItemResponse.Builder response = CSGameFightMonsterTideFightItemResponse.newBuilder();
        long userId = clientParam.getUserId();

        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserMonsterTideInfo userMonsterTideInfo = FightManager.getUserMonsterTiedInfo(userId);

        if (userMonsterTideInfo == null || userMonsterTideInfo.getNextMonsterTideId() == 0 || userMonsterTideInfo.getNextTime() == 0) {
            return ErrorWord.WRONG_STATUS;
        }

        UserPower userPower = GameUser.getUserPower(userId);
        long userCurPower = userPower.getPower();// 玩家的当前战力
        MonsterTideMain monsterTideMainNext = FightManager.getMonsterTideMain(userMonsterTideInfo.getNextMonsterTideId());// 下一波兽潮
        if (monsterTideMainNext == null || userCurPower < monsterTideMainNext.getPower()) {
            return ErrorWord.NOT_DATA_1;// 玩家战力不足下一波
        }

        int itemId = AllParam.MONSTER_TIDE_COST[0];// 需要消耗的道具
        long subNum = AllParam.MONSTER_TIDE_COST[1];// 需要消耗的道具数量
        long userItemNum = BagManager.getUserItemNum(userInfo, itemId);
        if (userItemNum < subNum) {
            return ErrorWord.ITEM_LACK;// 道具不足
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        RewardManager.subReward(userInfo, itemId, subNum, pbUserData, LogType.FIGHT_MONSTER_TIDE,userMonsterTideInfo.getNextMonsterTideId());// 扣除道具

        UserAffair userAffair = GameUser.getUserAffair(userId);
        FightManager.monsterTideFight(pbUserData, userInfo, userPower, userMonsterTideInfo, userAffair);

        MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_239, 1);// 更新主线任务,成就,日常任务的进度
        RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_239, 1);

        return response;
    }

    // CMD_GAME_FIGHT_MONSTER_TIDE_GUIDE_REWARD = 71006;// 领取兽潮引导奖励
    public static Object CMD_GAME_FIGHT_MONSTER_TIDE_GUIDE_REWARD(RequestParam clientParam) throws Exception {
        CSGameFightMonsterTideGuideRewardRequest request = CSGameFightMonsterTideGuideRewardRequest.parseFrom(clientParam.getData());
        CSGameFightMonsterTideGuideRewardResponse.Builder response = CSGameFightMonsterTideGuideRewardResponse.newBuilder();
        long userId = clientParam.getUserId();

        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserAffair userAffair = GameUser.getUserAffair(userId);
        String reward = AllParam.GUIDE_MONSTER_REWARD;// 新手引导兽潮来袭完成奖励
        if (userAffair.getIsMonsterGuide() == 0 && !Tool.isEmpty(AllParam.GUIDE_MONSTER_REWARD)) {
            PBUserData.Builder pbUserData = response.getUserBuilder();
            RewardManager.addReward(userInfo, CommonUtils.takeReawrdItemFromStr(reward), pbUserData, LogType.FIGHT_MONSTER_TIDE, "guide");//
            userAffair.putIsMonsterGuide(1);
            userAffair.update();
        }

        return response;
    }


    // CMD_GAME_FIGHT_SNATCH_MAIN_INFO = 71011;// 物资争夺
    public static Object CMD_GAME_FIGHT_SNATCH_MAIN_INFO(RequestParam clientParam) throws Exception {
        CSGameFightSnatchMainInfoRequest request = CSGameFightSnatchMainInfoRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchMainInfoResponse.Builder response = CSGameFightSnatchMainInfoResponse.newBuilder();
        long userId = clientParam.getUserId();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);
        ProtoDataUtils.updatePBUserData(pbUserData, userSnatchInfo, true);
        List<UserSnatchPartner> list = FightManager.getUserSnatchPartnerList(userId);
        for (UserSnatchPartner userSnatchPartner : list) {
            ProtoDataUtils.updatePBUserData(pbUserData, userSnatchPartner, true);
        }
        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserSnatchScore userSnatchScore = FightManager.getUserSnatchScore(userId);
        ProtoDataUtils.updatePBUserData(pbUserData, userSnatchScore, true);
        int myRank = FightManager.getMyRankSnatch(userInfo, userSnatchScore);
        response.setMyRank(myRank);

        // 下发快速战斗的队伍列表
        List<UserSnatchTeam> teamList = FightManager.getUserSnatchTeamList(userId);
        for (UserSnatchTeam userSnatchTeam : teamList) {
            ProtoDataUtils.updatePBUserData(pbUserData, userSnatchTeam, true);
        }

        return response;
    }


    // CMD_GAME_FIGHT_SNATCH_MATCH_PARTNER_SET = 71012;// 物资争夺匹配战确定干员上阵的阵容,匹配对手
    public static Object CMD_GAME_FIGHT_SNATCH_MATCH_PARTNER_SET(RequestParam clientParam) throws Exception {
        CSGameFightSnatchMatchPartnerSetRequest request = CSGameFightSnatchMatchPartnerSetRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchMatchPartnerSetResponse.Builder response = CSGameFightSnatchMatchPartnerSetResponse.newBuilder();
        long userId = clientParam.getUserId();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        if (!FightManager.isSnatchRankIng(TimeUtils.getCurTime())) {
            return ErrorWord.WRONG_STATUS;// 不在冲榜时间内
        }

        List<Integer> partnerIdList = request.getPartnerIdList();// 上阵的干员列表
        if (partnerIdList.size() == 0 || partnerIdList.size() > AllParam.SNATCH_PARTNER_NUM_MAX) {
            return ErrorWord.ALREADY_MAX;// 数量不对
        }

        JsonArray jsonArray = new JsonArray();
        for (Integer partnerId : partnerIdList) {
            UserPartner userPartner = PartnerManager.getUserPartner(userId, partnerId);
            if (userPartner == null) {
                return ErrorWord.WRONG_STATUS;// 有干员未获得
            }
            UserSnatchPartner userSnatchPartner = FightManager.getUserSnatchPartner(userId, partnerId);
            if (userSnatchPartner != null && userSnatchPartner.getMatchFightNum() >= AllParam.SNATCH_MATCH_FIGHT_NUM_MAX) {
                return ErrorWord.ALREADY_MAX;// 已经达到战斗次数上限
            }
            jsonArray.add(partnerId);
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserInfo userInfo =  GameUser.getUserInfo(userId);
        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);
        userSnatchInfo.putPartnerIds(jsonArray.toString());// 更新匹配战上阵的干员列表
        int rankType = RankConstant.SERVER_RANK_POWER;
        int myRank = RankManager.getMyRank(rankType, userInfo.getServerId(), userInfo.getId(), "0");
        userSnatchInfo.putEnemyId(FightManager.getMatchEnemy(userInfo, myRank, userSnatchInfo.getLastEnemyId()));// 对手
        userSnatchInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userSnatchInfo);

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_MATCH_MAIN_INFO = 71013;// 物资争夺匹配战页面,下发对手的干员数据等, 对手战力会有变化 [2]每次打开请求
    public static Object CMD_GAME_FIGHT_SNATCH_MATCH_MAIN_INFO(RequestParam clientParam) throws Exception {
        CSGameFightSnatchMatchMainInfoRequest request = CSGameFightSnatchMatchMainInfoRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchMatchMainInfoResponse.Builder response = CSGameFightSnatchMatchMainInfoResponse.newBuilder();
        long userId = clientParam.getUserId();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);
        long eneymId = userSnatchInfo.getEnemyId();
        if (eneymId == 0)  {
            return ErrorWord.WRONG_STATUS;// 未匹配对手
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getEmemyBuilder();
        FightManager.takeMatchEnemyData(pbUserData, eneymId);

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_MATCH_INSPIRE = 71014;// 物资争夺匹配战战斗鼓舞
    public static Object CMD_GAME_FIGHT_SNATCH_MATCH_INSPIRE(RequestParam clientParam) throws Exception {
        CSGameFightSnatchMatchInspireRequest request = CSGameFightSnatchMatchInspireRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchMatchInspireResponse.Builder response = CSGameFightSnatchMatchInspireResponse.newBuilder();
        long userId = clientParam.getUserId();

        int inspireNum = request.getInspireNum();// 鼓舞次数
        if (inspireNum < 1 || inspireNum > 999) {
            return ErrorWord.BAD_PARAM;
        }

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        if (!FightManager.isSnatchRankIng(TimeUtils.getCurTime())) {
            return ErrorWord.WRONG_STATUS;// 不在冲榜时间内
        }

        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);
        int curNum = userSnatchInfo.getInspireNum();// 当前的次数
        int maxNum = AllParam.SNATCH_ISPIRE_MAX_NUM;// 次数上限
        if (curNum + inspireNum > maxNum) {
            return ErrorWord.ALREADY_MAX;// 次数上限
        }

        int itemId = ItemId.GOLD;// 扣除金币
        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserPower userPower = GameUser.getUserPower(userId);
        long subTotal = FightManager.countSnatchInspire(userPower, curNum, inspireNum);//  总的要扣除的道具数量
        long itemNum = BagManager.getUserItemNum(userInfo, itemId);// 金币数量
        if (itemNum < subTotal) {
            return ErrorWord.ITEM_LACK;// 金币不足
        }


        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        RewardManager.subReward(userInfo, itemId, subTotal, pbUserData, LogType.FIGHT_SNATCH_INSPIRE);
        userSnatchInfo.addInspireNum(inspireNum);
        userSnatchInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userSnatchInfo);
        MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_131, inspireNum);// 更新主线任务,成就,日常任务的进度
        RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_131, inspireNum);

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_MATCH_FIGHT = 71015;// 物资争夺匹配战开始战斗
    public static Object CMD_GAME_FIGHT_SNATCH_MATCH_FIGHT(RequestParam clientParam) throws Exception {
        CSGameFightSnatchMatchFightRequest request = CSGameFightSnatchMatchFightRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchMatchFightResponse.Builder response = CSGameFightSnatchMatchFightResponse.newBuilder();
        long userId = clientParam.getUserId();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        if (!FightManager.isSnatchRankIng(TimeUtils.getCurTime())) {
            return ErrorWord.WRONG_STATUS;// 不在冲榜时间内
        }

        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);
        long enemyId = userSnatchInfo.getEnemyId();// 对手的userid
        if (enemyId == 0) {
            return ErrorWord.NOT_DATA_1;//  对手不存在
        }

        JsonArray partnerIdList = userSnatchInfo.takePartnerIds();
        if (partnerIdList.size() == 0) {
            return ErrorWord.WRONG_STATUS;// 没有上阵的干员
        }

        int fightNum = 1;// 战斗次数
        UserPower userPower = GameUser.getUserPower(userId);
        List<Long> myPowerList = new ArrayList<>();// 我方上阵的干员战力列表
        List<UserSnatchPartner> userSnatchPartnerList = new ArrayList<>();//
        List<UserPartner> partnerList = new ArrayList<>();
        int inspireValue = FightManager.countInspireValue(userSnatchInfo.getInspireNum());// 鼓舞加成值4000，表示加成40%
        for (int i=0;i<partnerIdList.size(); i++) {
            int partnerId = partnerIdList.getInteger(i);
            UserPartner userPartner = PartnerManager.getUserPartner(userId, partnerId);
            if (userPartner == null) {
                return ErrorWord.WRONG_STATUS;// 有干员未获得
            }
            UserSnatchPartner userSnatchPartner = FightManager.getUserSnatchPartner(userId, partnerId);
            if (userSnatchPartner.getMatchFightNum() + fightNum > AllParam.SNATCH_MATCH_FIGHT_NUM_MAX) {
                return ErrorWord.ALREADY_MAX;// 次数达到上限了
            }
            userSnatchPartnerList.add(userSnatchPartner);
            partnerList.add(userPartner);
            int skillAdd = SkillManager.getSkillMoudleAdd(userId, SkillConstant.EFFECT_TYPE_4, userPartner.getCharacterType());// 干员技能加成,秘书技能加成
            long myPartnerPower = GameUser.countPowerByPartner(userId, partnerId, userPartner, userPower, inspireValue + skillAdd);// 该干员的战力
            myPowerList.add(myPartnerPower);
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserInfo userInfo = GameUser.getUserInfo(userId);
        int serverId = userInfo.getServerId();
        List<Long> powerTargetList = FightManager.getPowerList(enemyId);// 获取对方当前的战力列表
        int koNum = FightManager.countKoNum(myPowerList, powerTargetList);// 击败对方干员的数量
        int failNum = FightManager.countFailNum(myPowerList, powerTargetList);// 我方被击败的数量
        response.setKoNum(koNum);// 下发击败的人数
        FightManager.handleUpdateMyTask(pbUserData, userInfo, koNum, failNum);// 战斗结束更新我方的各种任务进度
        MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_28, fightNum);// 挑战N场 更新主线任务,成就,日常任务的进度
        RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_28, fightNum);
        FightManager.createSnatchFame(userInfo, enemyId, koNum);// 生成名人广播数据
        FightManager.sendSnatchFightReward(pbUserData, userInfo, userSnatchInfo, koNum, fightNum, LogType.FIGHT_SNATCH_FIGHT);// 发放战斗奖励
        FightManager.updateSnatchPartnerFightNum(pbUserData, userSnatchPartnerList, 0, fightNum);// 更新物资争夺匹配战的上阵干员的数据// 更新物资争夺的上阵干员的数据战斗次数
        if (koNum > 0) {
            userSnatchInfo.updateMaxKoNum(pbUserData, userInfo, koNum);// 物资争夺单场达到{0}连胜
        }

        // 清空上阵数据,对手数据,鼓舞次数
        if (userSnatchInfo.getDateKey() == 0) {// 上期奖励领取完,再更新,避免 玩家奖励漏领
            userSnatchInfo.putDateKey(TimeUtils.getWeekOneTime(1, 0));// 本周1的0点0分
        }
        userSnatchInfo.putPartnerIds("");
        userSnatchInfo.putInspireNum(0);
        userSnatchInfo.putEnemyId(0);
        userSnatchInfo.putLastEnemyId(enemyId);// 记录下来上次打的人,不能重复打
        userSnatchInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userSnatchInfo);


        // 增加我的分数并更新榜单，扣除对方的分数并更新对方的榜单
        Lock lock = null;
        String lockKey = "";
        int addScore = FightManager.getAddScore(koNum);// 我方增加的分数
        int subScore = FightManager.getSubScore(koNum);// 对方扣除的物资数量
        // 生成对方的战报数据
        FightManager.createSnatchRecord(enemyId, userInfo, koNum, subScore);
        response.setSubScore(subScore);// 下发对方扣的分数
        try {
            lockKey = LockKey.getSnatchLock(serverId);
            lock = MainService.getVertLock(lockKey);

            UserSnatchScore userSnatchScore = FightManager.getUserSnatchScore(userId);
            userSnatchScore.addScore(pbUserData, userInfo, partnerList, addScore, LogType.FIGHT_SNATCH_FIGHT);
            userSnatchScore.update();
            // 下发我的榜单数据
            int myRank = FightManager.getMyRankSnatch(userInfo, userSnatchScore);
            response.setMyRank(myRank);

            UserInfo userInfoEnemy = GameUser.getUserInfo(enemyId);
            UserSnatchScore userSnatchScoreTarget = FightManager.getUserSnatchScore(enemyId);
            userSnatchScoreTarget.subScore(userInfoEnemy, partnerList, subScore, LogType.FIGHT_SNATCH_FIGHT);
            userSnatchScoreTarget.update();
        } catch (InvalidProtocolBufferException e) {
            return ErrorWord.PROTOCOL_PARSE_FAILED;
        } finally {// 释放锁
            MainService.releaseVertLock(lock);
        }

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_TRANSFER_LEVEL_UP = 71021;// 物资争夺中转站升级
    public static Object CMD_GAME_FIGHT_SNATCH_TRANSFER_LEVEL_UP(RequestParam clientParam) throws Exception {
        CSGameFightSnatchTransferLevelUpRequest request = CSGameFightSnatchTransferLevelUpRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchTransferLevelUpResponse.Builder response = CSGameFightSnatchTransferLevelUpResponse.newBuilder();
        long userId = clientParam.getUserId();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);
        int curLevel = userSnatchInfo.getTransferLevel();//当前等级
        int nextLevel = curLevel + 1;// 下个等级
        SnatchTransfer snatchTransferCur = FightManager.getSnatchTransfer(curLevel);// 当前的配置
        SnatchTransfer snatchTransfer = FightManager.getSnatchTransfer(nextLevel);
        if (snatchTransfer == null) {
            return ErrorWord.NOT_DATA;
        }
        int itemId = ItemId.FIGHT_SNATCH_TRANSFER_ITEM;
        long subNum = snatchTransfer.getConsume();
        UserInfo userInfo = GameUser.getUserInfo(userId);
        if (BagManager.getUserItemNum(userInfo, itemId) < subNum)  {
            return ErrorWord.ITEM_LACK;// 道具不足
        }

        // 执行逻辑
        UserPower userPower = GameUser.getUserPower(userId);
        PBUserData.Builder pbUserData = response.getUserBuilder();
        long curTime = TimeUtils.getCurTime();
        long addNum = FightManager.getSnatchTransferRewardNum(userPower, userSnatchInfo, snatchTransferCur, curTime);// 收益数量
        RewardManager.addReward(userInfo, ItemId.GOLD, addNum, pbUserData, LogType.FIGHT_SNATCH_TRANSFER_REWARD);//
        userSnatchInfo.putTransferTime(curTime);// 领取完之前存储的金币奖励

        RewardManager.subReward(userInfo, itemId, subNum, pbUserData, LogType.FIGHT_SNATCH_TRANSFER_LEVEL_UP);// 扣除道具
        userSnatchInfo.putTransferLevel(nextLevel);
        userSnatchInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userSnatchInfo);
        MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_127, 1);// 更新主线任务,成就,日常任务的进度
        RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_127, 1);

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_TRANSFER_GET_REWARD = 71022;// 物资争夺中转站领取奖励
    public static Object CMD_GAME_FIGHT_SNATCH_TRANSFER_GET_REWARD(RequestParam clientParam) throws Exception {
        CSGameFightSnatchTransferGetRewardRequest request = CSGameFightSnatchTransferGetRewardRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchTransferGetRewardResponse.Builder response = CSGameFightSnatchTransferGetRewardResponse.newBuilder();
        long userId = clientParam.getUserId();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);
        int curLevel = userSnatchInfo.getTransferLevel();//当前等级
        SnatchTransfer snatchTransfer = FightManager.getSnatchTransfer(curLevel);
        if (snatchTransfer == null) {
            return ErrorWord.NOT_DATA;
        }
        int itemId = ItemId.GOLD;
        long curTime = TimeUtils.getCurTime();
        if (curTime - userSnatchInfo.getTransferTime() < AllParam.SNATCH_TRANSFER_REWARD_TIME) {
            return ErrorWord.WRONG_STATUS;// 有奖励未领取 3秒算一次产出
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserPower userPower = GameUser.getUserPower(userId);
        long addNum = FightManager.getSnatchTransferRewardNum(userPower, userSnatchInfo, snatchTransfer, curTime);// 收益数量
        RewardManager.addReward(userInfo, itemId, addNum, pbUserData, LogType.FIGHT_SNATCH_TRANSFER_REWARD);//
        userSnatchInfo.putTransferTime(curTime);
        userSnatchInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userSnatchInfo);
        MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_140, 1);// 更新主线任务,成就,日常任务的进度
        RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_140, 1);

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_RANK_GET_REWARD = 71023;// 物资争夺领取榜单奖励
    public static Object CMD_GAME_FIGHT_SNATCH_RANK_GET_REWARD(RequestParam clientParam) throws Exception {
        CSGameFightSnatchRankGetRewardRequest request = CSGameFightSnatchRankGetRewardRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchRankGetRewardResponse.Builder response = CSGameFightSnatchRankGetRewardResponse.newBuilder();
        long userId = clientParam.getUserId();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);
        long dateKey = userSnatchInfo.getDateKey();
        if (dateKey == 0 || !FightManager.isSnathcRankClose(dateKey)) {
            return ErrorWord.WRONG_STATUS;//  冲榜未结束
        }

        UserInfo userInfo = GameUser.getUserInfo(userId);
        int myRank = RankManager.getMyRank(RankConstant.SERVER_RANK_SNATCH, userInfo.getServerId(), userId, TimeUtils.getDayStr(dateKey));
        RankReward rankReward = RankManager.getRankReward(RankConstant.SERVER_RANK_SNATCH, myRank);
        if (rankReward == null) {
            return ErrorWord.NOT_DATA;// 未上榜
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        RewardManager.addReward(userInfo, CommonUtils.takeReawrdItemFromStr(rankReward.getReward()), pbUserData, LogType.FIGHT_SNATCH_RANK_REWARD, myRank);//
        userSnatchInfo.putDateKey(0);// 设置=0,打人有上榜的时候才会设置datekey,
        userSnatchInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userSnatchInfo);

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_RECORD = 71024;// 物资争夺查看战报,我方的被打记录 [3]每次打开请求增量下发
    public static Object CMD_GAME_FIGHT_SNATCH_RECORD(RequestParam clientParam) throws Exception {
        CSGameFightSnatchRecordRequest request = CSGameFightSnatchRecordRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchRecordResponse.Builder response = CSGameFightSnatchRecordResponse.newBuilder();
        long userId = clientParam.getUserId();
        long dbid = request.getDbid();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        PBUserData.Builder pbUserData = response.getUserBuilder();
        List<UserSnatchRecord> list = FightManager.getUserSnatchRecordList(userId);
        for (UserSnatchRecord entity : list) {
            if (TimeUtils.getTimeDiff(entity.getAddTime()) >= TimeUtils.WEEK) {
                entity.delete();// 守备列表仅记录玩家近7天的被攻击信息
            } else {
                if (entity.getId() > dbid) {
                    ProtoDataUtils.updatePBUserData(pbUserData, entity, true);
                }
            }
        }

        return response;
    }


    // CMD_GAME_FIGHT_SNATCH_OFFER_PUBLISH = 71019;// 物资争夺 发布悬赏
    public static Object CMD_GAME_FIGHT_SNATCH_OFFER_PUBLISH(RequestParam clientParam) throws Exception {
        CSGameFightSnatchOfferPublishRequest request = CSGameFightSnatchOfferPublishRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchOfferPublishResponse.Builder response = CSGameFightSnatchOfferPublishResponse.newBuilder();
        long userId = clientParam.getUserId();

        long userIdTarget = request.getUid();
        boolean isPro = request.getType() == 1 ? true : false;// 是否高级悬赏

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        if (!FightManager.isSnatchRankIng(TimeUtils.getCurTime())) {
            return ErrorWord.WRONG_STATUS;// 不在冲榜时间内
        }

        int itemId = isPro ? ItemId.FIGHT_SNATCH_OFFER_ITEM_PRO : ItemId.FIGHT_SNATCH_OFFER_ITEM;// 需要消耗的道具
        int rewardItemId = AllParam.SNATCH_OFFER_PUBLIC_REWARD[0];//  发布悬赏的玩家可获得50个钻石，若使用高级悬赏令发布则获得250个钻石
        long rewardNum = isPro ? AllParam.SNATCH_OFFER_PUBLIC_REWARD[1] * AllParam.SNATCH_FIGHT_PRO_MUL : AllParam.SNATCH_OFFER_PUBLIC_REWARD[1];
        UserInfo userInfo = GameUser.getUserInfo(userId);
        int serverId = userInfo.getServerId();
        if (BagManager.getUserItemNum(userInfo, itemId) == 0) {
            return ErrorWord.ITEM_LACK;// 道具不足
        }
        UserInfo userInfoTarget = GameUser.getUserInfo(userIdTarget);
        if (userInfoTarget == null || userInfoTarget.getServerId() != serverId || userIdTarget == userId) {
            return ErrorWord.NOT_DATA;// 不是本服的玩家
        }

        Lock lock = null;
        try {
            lock = MainService.getVertLock(LockKey.getSnatchLock(serverId));
            ServerSnatchOffer serverSnatchOffer = FightManager.getServerSnatchOffer(serverId, userIdTarget);
            if (serverSnatchOffer != null && (TimeUtils.getCurTime() - serverSnatchOffer.getCompleteTime() < 1)) {
                return ErrorWord.WRONG_STATUS;// 结束1秒后才可以再次悬赏，避免跟定时服同时操作数据，导致异常
            }
            // 执行发布悬赏
            serverSnatchOffer = FightManager.createServerSnatchOffer(userInfo, userInfoTarget, isPro, serverSnatchOffer);
            response.setOfferInfo(serverSnatchOffer.takeInitBuilder());// 下发给客户端
            // 创建定时任务
            JsonObject jsonObject = new JsonObject();
            jsonObject.put("user_id", userIdTarget);
            jsonObject.put("server_id", userInfo.getServerId());
            jsonObject.put("end_time", serverSnatchOffer.getPublishTime() + AllParam.SNATCH_OFFER_DURATION_TIME);
            TimedTaskManager.sendMainTaskRetry(TimeTaskCmd.MAIN_SERVER_SNATCH_OFFER, jsonObject);// 发送失败,需要进行重发
        } catch (InvalidProtocolBufferException e) {
            return ErrorWord.PROTOCOL_PARSE_FAILED;
        } finally {// 释放锁
            MainService.releaseVertLock(lock);
        }

        PBUserData.Builder pbUserData = response.getUserBuilder();
        RewardManager.subReward(userInfo, itemId, 1, pbUserData, LogType.FIGHT_SNATCH_OFFER_PUBLIC, userIdTarget);
        RewardManager.addReward(userInfo, rewardItemId, rewardNum, pbUserData, LogType.FIGHT_SNATCH_OFFER_PUBLIC, userIdTarget);

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_OFFER_LIST = 71017;// 物资争夺悬赏名单列表  公共数据. [2]每次打开请求
    public static Object CMD_GAME_FIGHT_SNATCH_OFFER_LIST(RequestParam clientParam) throws Exception {
        CSGameFightSnatchOfferListRequest request = CSGameFightSnatchOfferListRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchOfferListResponse.Builder response = CSGameFightSnatchOfferListResponse.newBuilder();
        long userId = clientParam.getUserId();


        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        if (!FightManager.isSnatchRankIng(TimeUtils.getCurTime())) {
            return ErrorWord.WRONG_STATUS;// 不在冲榜时间内
        }

        UserInfo userInfo = GameUser.getUserInfo(userId);
        int serverId = userInfo.getServerId();
        List<ServerSnatchOffer> list = FightManager.getServerSnatchOfferList(serverId);
        for (ServerSnatchOffer serverSnatchOffer : list) {
            if (TimeUtils.getTimeDiff(serverSnatchOffer.getPublishTime()) < TimeUtils.WEEK) {// 悬赏列表上仅保留近7天的悬赏信息
                response.addOfferlist(serverSnatchOffer.takeInitBuilder().build());
            }
        }

        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);
        ProtoDataUtils.updatePBUserData(response.getUserBuilder(), userSnatchInfo, true);

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_OFFER_FIGHT = 71027;// 物资争夺悬赏进行追击
    public static Object CMD_GAME_FIGHT_SNATCH_OFFER_FIGHT(RequestParam clientParam) throws Exception {
        CSGameFightSnatchOfferFightRequest request = CSGameFightSnatchOfferFightRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchOfferFightResponse.Builder response = CSGameFightSnatchOfferFightResponse.newBuilder();
        long userId = clientParam.getUserId();

        int inspireNum = request.getInspireNum();// 鼓舞次数
        if (inspireNum < 0 || inspireNum > AllParam.SNATCH_ISPIRE_MAX_NUM) {
            return ErrorWord.BAD_PARAM;
        }

        long userIdTarget = request.getUid();
        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        if (!FightManager.isSnatchRankIng(TimeUtils.getCurTime())) {
            return ErrorWord.WRONG_STATUS;// 不在冲榜时间内
        }

        List<Integer> partnerIdList = request.getPartnerIdList();// 上阵的干员列表
        if (partnerIdList.size() == 0 || partnerIdList.size() > AllParam.SNATCH_PARTNER_NUM_MAX) {
            return ErrorWord.ALREADY_MAX;// 数量不对
        }

        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserPower userPower = GameUser.getUserPower(userId);
        List<Long> myPowerList = new ArrayList<>();// 我方上阵的干员战力列表
        List<UserPartner>  partnerList = new ArrayList<>();
        int inspireValue = FightManager.countInspireValue(inspireNum);// 鼓舞加成值4000，表示加成40%
        for (Integer partnerId : partnerIdList) {
            UserPartner userPartner = PartnerManager.getUserPartner(userId, partnerId);
            if (userPartner == null) {
                return ErrorWord.WRONG_STATUS;// 有干员未获得
            }
            int skillAdd = SkillManager.getSkillMoudleAdd(userId, SkillConstant.EFFECT_TYPE_4, userPartner.getCharacterType());// 干员技能加成,秘书技能加成
            long myPartnerPower = GameUser.countPowerByPartner(userId, partnerId, userPartner, userPower, inspireValue + skillAdd);// 该干员的战力
            myPowerList.add(myPartnerPower);
            partnerList.add(userPartner);
        }


        int itemId = ItemId.GOLD;
        long userItemNum = BagManager.getUserItemNum(userInfo, itemId);
        long subTotal = FightManager.countSnatchInspire(userPower, 0, inspireNum);// 鼓舞需要消耗的金币数量
        if (userItemNum < subTotal) {
            return ErrorWord.ITEM_LACK;// 金币数量不足
        }

        PBUserData.Builder pbUserData = response.getUserBuilder();
        int serverId = userInfo.getServerId();
        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);

        Lock lock = null;
        int koNum = 0;// 击败的干员数量
        int failNum = 0;// 我方被打败的干员数量
        int fightNum = 0;// 追击次数,奖励的倍数
        try {
            lock = MainService.getVertLock(LockKey.getSnatchLock(serverId));
            ServerSnatchOffer serverSnatchOffer = FightManager.getServerSnatchOffer(serverId, userIdTarget);
            if (serverSnatchOffer == null || serverSnatchOffer.isComplete()) {
                return ErrorWord.ENTITY_NOT_EXIST;// 悬赏已结束
            }
            JsonArray jsonArray = serverSnatchOffer.getFighterArray();
            if (Tool.isInList(jsonArray, userId)) {
                return ErrorWord.REPEATED_OPERATION;// 已经追击过了
            }

            fightNum = serverSnatchOffer.isOfferPro() ? AllParam.SNATCH_FIGHT_PRO_MUL : 1;// 消耗的追击次数
            if (userSnatchInfo.getOfferFightNum() + fightNum > AllParam.SNATCH_OFFER_FIGHT_MAX_DAY) {
                return ErrorWord.ALREADY_MAX;// 次数达到上限
            }

            List<Long> powerTargetList = serverSnatchOffer.getPowerList();// 悬赏对象的干员快照，战力列表
            koNum = FightManager.countKoNum(myPowerList, powerTargetList);// 本次战斗，打败对方N名干员
            failNum = FightManager.countFailNum(myPowerList, powerTargetList);// 本次战斗，我方被对方打败N名干员

            jsonArray.add(userId);// 记录追击记录
            serverSnatchOffer.putFighter(jsonArray.toString());
            
            serverSnatchOffer.addKoNum(koNum);
            if (serverSnatchOffer.isComplete()) {
                serverSnatchOffer.sendCompleteReward();
                serverSnatchOffer.putCompleteTime(TimeUtils.getCurTime());
            }
            FightManager.addServerSanchOfferFightInfo(serverSnatchOffer, userInfo, koNum);// // 添加本服的悬赏战斗数据
            serverSnatchOffer.update();

            // 增加我的分数并更新榜单，扣除对方的分数并更新对方的榜单
            int addScore = FightManager.getAddScore(koNum);// 我方增加的分数
            int subScore = FightManager.getSubScore(koNum);// 对方扣除的物资数量
            response.setKoNum(koNum);// 下发击败的人数
            response.setSubScore(subScore);// 下发对方扣的分数
            UserSnatchScore userSnatchScore = FightManager.getUserSnatchScore(userId);
            userSnatchScore.addScore(pbUserData, userInfo, partnerList, addScore, LogType.FIGHT_SNATCH_FIGHT);
            userSnatchScore.update();
            // 下发我的榜单数据
            int myRank = FightManager.getMyRankSnatch(userInfo, userSnatchScore);
            response.setMyRank(myRank);

            UserInfo userinfoTarget = GameUser.getUserInfo(userIdTarget);
            UserSnatchScore userSnatchScoreTarget = FightManager.getUserSnatchScore(userIdTarget);
            userSnatchScoreTarget.subScore(userinfoTarget, partnerList, subScore, LogType.FIGHT_SNATCH_FIGHT);
            userSnatchScoreTarget.update();

            // 生成对方的仇人记录
            FightManager.createSnatchEnemy(userIdTarget, userInfo, koNum, subScore);
        } catch (InvalidProtocolBufferException e) {
            return ErrorWord.PROTOCOL_PARSE_FAILED;
        } finally {// 释放锁
            MainService.releaseVertLock(lock);
        }


        FightManager.handleUpdateMyTask(pbUserData, userInfo, koNum, failNum);// 战斗结束更新我方的各种任务进度
        MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_28, 1);// 挑战N场 更新主线任务,成就,日常任务的进度
        RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_28, 1);
        FightManager.sendSnatchFightReward(pbUserData, userInfo, userSnatchInfo, koNum, fightNum, LogType.FIGHT_SNATCH_OFFER_FIGHT);// 发放战斗奖励
        if (koNum > 0) {
            userSnatchInfo.updateMaxKoNum(pbUserData, userInfo, koNum);// 物资争夺单场达到{0}连胜
        }
        userSnatchInfo.addOfferFightNum(fightNum);
        userSnatchInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userSnatchInfo);

        RewardManager.subReward(userInfo, itemId, subTotal, pbUserData, LogType.FIGHT_SNATCH_OFFER_FIGHT);// 扣除鼓舞消耗的金币
        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_FAME_LIST = 71028;// 物资争夺名人榜列表,公共数据. [2]每次打开请求
    public static Object CMD_GAME_FIGHT_SNATCH_FAME_LIST(RequestParam clientParam) throws Exception {
        CSGameFightSnatchFameListRequest request = CSGameFightSnatchFameListRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchFameListResponse.Builder response = CSGameFightSnatchFameListResponse.newBuilder();
        long userId = clientParam.getUserId();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        // 执行逻辑
        UserInfo userInfo = GameUser.getUserInfo(userId);
        List<ServerSnatchFame> list = FightManager.getServerSnatchFameList(userInfo.getServerId());
        for (ServerSnatchFame serverSnatchFame : list) {
            if (TimeUtils.isToday(serverSnatchFame.getDateTime())) {
                response.addFameList(serverSnatchFame.takeInitBuilder().build());
            } else {
                serverSnatchFame.delete();// 删除昨天的数据
            }
        }

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_ENEMY_LIST = 71029;// 物资争夺查看仇人列表,我方的被打记录 [3]每次打开请求增量下发
    public static Object CMD_GAME_FIGHT_SNATCH_ENEMY_LIST(RequestParam clientParam) throws Exception {
        CSGameFightSnatchEnemyListRequest request = CSGameFightSnatchEnemyListRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchEnemyListResponse.Builder response = CSGameFightSnatchEnemyListResponse.newBuilder();
        long userId = clientParam.getUserId();
        long dbid = request.getDbid();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        PBUserData.Builder pbUserData = response.getUserBuilder();
        List<UserSnatchEnemy> list = FightManager.getUsersnatchEnemyList(userId);
        for (UserSnatchEnemy entity : list) {
            if (TimeUtils.getTimeDiff(entity.getAddTime()) >= TimeUtils.DAY * 15) {
                entity.delete();// 最多保留15天
            } else {
                if (entity.getId() > dbid) {
                    ProtoDataUtils.updatePBUserData(pbUserData, entity, true);
                }
            }
        }

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_CHALLENGE = 71030;// 物资争夺对名人榜的玩家/仇人发起挑战
    public static Object CMD_GAME_FIGHT_SNATCH_CHALLENGE(RequestParam clientParam) throws Exception {
        CSGameFightSnatchChallengeRequest request = CSGameFightSnatchChallengeRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchChallengeResponse.Builder response = CSGameFightSnatchChallengeResponse.newBuilder();
        long userId = clientParam.getUserId();

        int inspireNum = request.getInspireNum();// 鼓舞次数
        if (inspireNum < 0 || inspireNum > AllParam.SNATCH_ISPIRE_MAX_NUM) {
            return ErrorWord.BAD_PARAM;
        }

        int type = request.getType();// 0-挑战名人榜，1-挑战仇人
        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        if (!FightManager.isSnatchRankIng(TimeUtils.getCurTime())) {
            return ErrorWord.WRONG_STATUS;// 不在冲榜时间内
        }

        UserInfo userInfo = GameUser.getUserInfo(userId);
        UserPower userPower = GameUser.getUserPower(userId);
        int serverId = userInfo.getServerId();
        int itemId = request.getIsPro() ? ItemId.FIGHT_SNATCH_CHALLENGE_ITEM_PRO : ItemId.FIGHT_SNATCH_CHALLENGE_ITEM;
        int fightNum = request.getIsPro() ? AllParam.SNATCH_FIGHT_PRO_MUL : 1;// 战斗次数
        int rewardMul = request.getIsPro() ? AllParam.SNATCH_CHALLENGE_PRO_MUL : 1;// 奖励的倍数
        long userItemNum = BagManager.getUserItemNum(userInfo, itemId);
        if (userItemNum < 1) {
            return ErrorWord.ITEM_LACK;
        }

        int itemGold = ItemId.GOLD;
        long userItemNum2 = BagManager.getUserItemNum(userInfo, itemGold);
        long subTotal = FightManager.countSnatchInspire(userPower, 0, inspireNum);// 鼓舞需要消耗的金币数量
        if (userItemNum2 < subTotal) {
            return ErrorWord.ITEM_LACK;// 金币数量不足
        }

        ServerSnatchFame serverSnatchFame = FightManager.getServerSnatchFame(serverId, request.getDbid());
        UserSnatchEnemy userSnatchEnemy = FightManager.getUserSnatchEnemy(userId, request.getDbid());
        long userIdTarget = 0L;
        if (type == 1) {//挑战仇人
            if (userSnatchEnemy == null) {
                return ErrorWord.ENTITY_NOT_EXIST;// 仇人信息不存在
            }
            userIdTarget = userSnatchEnemy.getEnemyId();
        } else {//挑战名人榜
            if (serverSnatchFame == null || !TimeUtils.isToday(serverSnatchFame.getDateTime())) {
                return ErrorWord.ENTITY_NOT_EXIST;// 已经过期了
            }
            userIdTarget = serverSnatchFame.getAttactId();// 对手的userid
        }

        List<Integer> partnerIdList = request.getPartnerIdList();// 上阵的干员列表
        if (partnerIdList.size() == 0 || partnerIdList.size() > AllParam.SNATCH_PARTNER_NUM_MAX) {
            return ErrorWord.ALREADY_MAX;// 数量不对
        }

        List<UserPartner> userPartnerList = new ArrayList<>();// 我方上阵的干员列表
        List<Long> myPowerList = new ArrayList<>();// 我方上阵的干员战力列表
        int inspireValue = FightManager.countInspireValue(inspireNum);// 鼓舞加成值4000，表示加成40%
        List<UserSnatchPartner> userSnatchPartnerList = new ArrayList<>();//
        for (Integer partnerId : partnerIdList) {
            UserPartner userPartner = PartnerManager.getUserPartner(userId, partnerId);
            if (userPartner == null) {
                return ErrorWord.WRONG_STATUS;// 有干员未获得
            }
            UserSnatchPartner userSnatchPartner = FightManager.getUserSnatchPartner(userId, partnerId);
            if (userSnatchPartner.getChallengeNum() + fightNum > AllParam.SNATCH_CHALLENGE_MAX_NUM) {
                return ErrorWord.ALREADY_MAX;// 次数达到上限了
            }
            userSnatchPartnerList.add(userSnatchPartner);
            int skillAdd = SkillManager.getSkillMoudleAdd(userId, SkillConstant.EFFECT_TYPE_4, userPartner.getCharacterType());// 干员技能加成,秘书技能加成
            long myPartnerPower = GameUser.countPowerByPartner(userId, partnerId, userPartner, userPower, inspireValue + skillAdd);// 该干员的战力
            myPowerList.add(myPartnerPower);
            userPartnerList.add(userPartner);
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        RewardManager.subReward(userInfo, itemId, 1, pbUserData, LogType.FIGHT_SNATCH_CHALLENGE);// 扣除挑战券
        RewardManager.subReward(userInfo, itemGold, subTotal, pbUserData, LogType.FIGHT_SNATCH_CHALLENGE);// 扣除鼓舞消耗的金币

        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);
        List<Long> powerTargetList = FightManager.getPowerList(userIdTarget);// 悬赏对象的干员快照，战力列表
        Lock lock = null;
        int koNum = FightManager.countKoNum(myPowerList, powerTargetList);// 本次战斗，打败对方N名干员
        int failNum = FightManager.countFailNum(myPowerList, powerTargetList);// 本次战斗，我方被对方打败N名干员
        try {
            lock = MainService.getVertLock(LockKey.getSnatchLock(serverId));

            // 增加我的分数并更新榜单，扣除对方的分数并更新对方的榜单
            int addScore = FightManager.getAddScore(koNum);// 我方增加的分数
            int subScore = FightManager.getSubScore(koNum);// 对方扣除的物资数量
            response.setKoNum(koNum);// 下发击败的人数
            response.setSubScore(subScore);// 下发对方扣的分数
            UserSnatchScore userSnatchScore = FightManager.getUserSnatchScore(userId);
            userSnatchScore.addScore(pbUserData, userInfo, userPartnerList, addScore, LogType.FIGHT_SNATCH_FIGHT);
            userSnatchScore.update();
            // 下发我的榜单数据
            int myRank = FightManager.getMyRankSnatch(userInfo, userSnatchScore);
            response.setMyRank(myRank);

            UserInfo userinfoTarget = GameUser.getUserInfo(userIdTarget);
            UserSnatchScore userSnatchScoreTarget = FightManager.getUserSnatchScore(userIdTarget);
            userSnatchScoreTarget.subScore(userinfoTarget, userPartnerList, subScore, LogType.FIGHT_SNATCH_FIGHT);
            userSnatchScoreTarget.update();

            if (type == 1) {// 挑战仇人，要删除仇人记录
                userSnatchEnemy.delete();
            } else {// 挑战名人榜 生成对方的仇人记录
                FightManager.createSnatchEnemy(userIdTarget, userInfo, koNum, subScore);
            }
        } catch (InvalidProtocolBufferException e) {
            return ErrorWord.PROTOCOL_PARSE_FAILED;
        } finally {// 释放锁
            MainService.releaseVertLock(lock);
        }
        FightManager.updateSnatchPartnerFightNum(pbUserData, userSnatchPartnerList, 1, fightNum);// 更新物资争夺匹配战的上阵干员的数据// 更新物资争夺的上阵干员的数据战斗次数
        FightManager.updateUserPartnerPower(pbUserData, userInfo, userPower, userPartnerList, koNum, rewardMul);// // 挑战成功给玩家上阵的干员增加战力加成
        FightManager.handleUpdateMyTask(pbUserData, userInfo, koNum, failNum);// 战斗结束更新我方的各种任务进度
        MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_28, 1);// 挑战N场 更新主线任务,成就,日常任务的进度
        RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_28, 1);
        FightManager.sendSnatchFightReward(pbUserData, userInfo, userSnatchInfo, koNum, rewardMul, LogType.FIGHT_SNATCH_CHALLENGE);// 发放战斗奖励
        if (koNum > 0) {
            userSnatchInfo.updateMaxKoNum(pbUserData, userInfo, koNum);// 物资争夺单场达到{0}连胜
        }
        if (type == 0) {// 挑战名人广播时才需要记录上一挑战的人
            userSnatchInfo.putLastEnemyid(serverSnatchFame.getId());
        }

        userSnatchInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userSnatchInfo);
        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_TEAM_SET = 71031;// 物资争夺 快速战斗队伍设置
    public static Object CMD_GAME_FIGHT_SNATCH_TEAM_SET(RequestParam clientParam) throws Exception {
        CSGameFightSnatchTeamSetRequest request = CSGameFightSnatchTeamSetRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchTeamSetResponse.Builder response = CSGameFightSnatchTeamSetResponse.newBuilder();
        long userId = clientParam.getUserId();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        UserInfo userInfo =  GameUser.getUserInfo(userId);
        UserAffair userAffair = GameUser.getUserAffair(userId);
        UserStage userStage = FightManager.getUserStage(userId);
        if (!SystemManager.checkModuleOpen(userInfo, userAffair, userStage, SystemConstant.SYSTEM_MODULE_ID_SNATCH_QUICK_FIGHT))  {
            return ErrorWord.WRONG_STATUS;// 未解锁物资争夺快速战斗功能
        }

        JsonArray partnerIdList = new JsonArray();//  总的干员id
        JsonArray teamIdList = new JsonArray();// 队伍Id列表
        List<PBUserSnatchTeam> list = request.getTeamList();
        for (PBUserSnatchTeam pbUserSnatchTeam : list) {
            if (pbUserSnatchTeam.getTeamId() > AllParam.SNATCH_FIGHT_TEAM_MAX) {
                return ErrorWord.ALREADY_MAX;// 不错超过20只队伍
            }
            teamIdList.add(pbUserSnatchTeam.getTeamId());
            List<Integer> partnerIdArray = pbUserSnatchTeam.getPartnerList();
            for (int i=0;i<partnerIdArray.size();i++) {
                int partnerId = partnerIdArray.get(i);
                UserPartner userPartner = PartnerManager.getUserPartner(userId, partnerId);
                if (userPartner == null) {
                    return ErrorWord.ENTITY_NOT_EXIST;// 干员不存在
                }
                UserSnatchPartner userSnatchPartner = FightManager.getUserSnatchPartner(userId, partnerId);
                if (userSnatchPartner != null && userSnatchPartner.getMatchFightNum() >= AllParam.SNATCH_MATCH_FIGHT_NUM_MAX) {
                    return ErrorWord.ALREADY_MAX;// 该干员没有战斗次数
                }
                if (Tool.isInList(partnerIdList, partnerId)) {
                    return ErrorWord.REPEATED_OPERATION;// 干员Id 重复了
                } else {
                    partnerIdList.add(partnerId);
                }
            }
        }

        // 执行逻辑
        PBUserData.Builder pbUserData = response.getUserBuilder();
        for (PBUserSnatchTeam pbUserSnatchTeam : list) {
            List<Integer> partnerIdArray = pbUserSnatchTeam.getPartnerList();
            JsonArray partnerIds = new JsonArray();
            for (int i=0;i<partnerIdArray.size();i++) {
                partnerIds.add(partnerIdArray.get(i));
            }
            int isInspire = pbUserSnatchTeam.getIsInspire();// 是否鼓舞20次
            int teamId = pbUserSnatchTeam.getTeamId();//
            FightManager.setSnatchTeam(pbUserData, userInfo, teamId, partnerIds, isInspire);// // 设置物资争夺快速战斗的队伍配置
        }

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_TEAM_FIGHT = 71032;// 物资争夺 进行快速战斗
    public static Object CMD_GAME_FIGHT_SNATCH_TEAM_FIGHT(RequestParam clientParam) throws Exception {
        CSGameFightSnatchTeamFightRequest request = CSGameFightSnatchTeamFightRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchTeamFightResponse.Builder response = CSGameFightSnatchTeamFightResponse.newBuilder();
        long userId = clientParam.getUserId();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        UserInfo userInfo =  GameUser.getUserInfo(userId);
        UserAffair userAffair = GameUser.getUserAffair(userId);
        UserStage userStage = FightManager.getUserStage(userId);
        if (!SystemManager.checkModuleOpen(userInfo, userAffair, userStage, SystemConstant.SYSTEM_MODULE_ID_SNATCH_QUICK_FIGHT))  {
            return ErrorWord.WRONG_STATUS;// 未解锁物资争夺快速战斗功能
        }

        List<UserSnatchTeam> list = FightManager.getUserSnatchTeamList(userId);
        if (list.size() == 0) {
            return ErrorWord.WRONG_STATUS;// 没有设置队伍
        }

        int serverId = userInfo.getServerId();

        // 给物资争夺快速战斗的队伍生成对手信息
        int rankType = RankConstant.SERVER_RANK_POWER;
        int myRank = RankManager.getMyRank(rankType, userInfo.getServerId(), userInfo.getId(), "0");
        UserPower userPower = GameUser.getUserPower(userId);
        long totalInspireGoldNum = FightManager.countSnatchInspire(userPower, 0, AllParam.SNATCH_FIGHT_TEAM_INSPIRE_NUM);// 鼓舞20次需要消耗的金币数量
        long goldNum = BagManager.getUserItemNum(userInfo, ItemId.GOLD);// 金币数量
        long subGoldNum = 0L;// 本次快速战斗总消耗的金币数量
        for (UserSnatchTeam userSnatchTeam : list) {
            userSnatchTeam.putEnemyId(userInfo, myRank);
            if (userSnatchTeam.getIsInspire() == 1 && goldNum >= totalInspireGoldNum) {
                userSnatchTeam.putInspireNum(AllParam.SNATCH_FIGHT_TEAM_INSPIRE_NUM);// 设置实际的鼓舞次数
                subGoldNum += totalInspireGoldNum;
                goldNum = goldNum - totalInspireGoldNum;
            } else {
                userSnatchTeam.putInspireNum(0);
            }
        }

        PBUserData.Builder pbUserData = response.getUserBuilder();
        UserSnatchInfo userSnatchInfo = FightManager.getUserSnatchInfo(userId);
        Lock lock = null;
        int totalFightNum = 0;// 总的战斗次数
        int totalKoNum = 0;
        int totalFailNum = 0;
        try {
            lock = MainService.getVertLock(LockKey.getSnatchLock(serverId));
            UserSnatchScore userSnatchScore = FightManager.getUserSnatchScore(userId);
            for (UserSnatchTeam userSnatchTeam : list) {
                List<UserPartner> partnerList = PartnerManager.getUserPartnerList(userId, userSnatchTeam.getPartnerArray());// 该队伍上阵的干员

                boolean isFight = userSnatchTeam.doFight(pbUserData, userInfo, userPower, partnerList, userSnatchInfo);// 扣除对手的分数，生成对手的战报，记录该队伍的战斗情况
                if (isFight) {
                    int koNum = userSnatchTeam.getKoNum();// 击败人数
                    int fightNum = userSnatchTeam.getFightNum();// 战斗次数
                    int addScore = FightManager.getAddScore(koNum);// 我方增加的分数

                    if (koNum > 0) {
                        // 实际增加的物资数量，有干员技能会加成
                        int addScoreNew = userSnatchScore.addScore(pbUserData, userInfo, partnerList, addScore, LogType.FIGHT_SNATCH_FIGHT, "teamId:" + userSnatchTeam.getTeamId() + " koNum:" + koNum + " fNum:" + fightNum);
                        userSnatchTeam.putAddScore(addScoreNew);

                        // 获得中转站的扩建工具
                        RewardManager.addReward(userInfo, ItemId.FIGHT_SNATCH_TRANSFER_ITEM, userSnatchTeam.getTransferItemNum(), pbUserData, LogType.FIGHT_SNATCH_FIGHT, "teamId:" + userSnatchTeam.getTeamId() + " koNum:" + koNum + " fNum:" + fightNum);

                        // 获得贸易币
                        RewardManager.addReward(userInfo, new RewardItem(ItemId.FIGHT_SNATCH_MONEY, userSnatchTeam.getSnatchMoneyNum(), userSnatchInfo), pbUserData, LogType.FIGHT_SNATCH_FIGHT, "teamId:" + userSnatchTeam.getTeamId() + " koNum:" + koNum + " fNum:" + fightNum);

                    }
                    totalFightNum += fightNum;
                    totalKoNum += koNum;
                    totalFailNum += userSnatchTeam.getFailNum();

                    userSnatchTeam.update();
                    ProtoDataUtils.updatePBUserData(pbUserData, userSnatchTeam);
                }
            }

            userSnatchScore.update();
            ProtoDataUtils.updatePBUserData(pbUserData, userSnatchScore);
        } catch (InvalidProtocolBufferException e) {
            return ErrorWord.PROTOCOL_PARSE_FAILED;
        } finally {// 释放锁
            MainService.releaseVertLock(lock);
        }

        // 更新我方的私有数据
        RewardManager.subReward(userInfo, ItemId.GOLD, subGoldNum, pbUserData, LogType.FIGHT_SNATCH_INSPIRE);
        FightManager.handleUpdateMyTask(pbUserData, userInfo, totalKoNum, totalFailNum);// 战斗结束更新我方的各种任务进度
        MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_28, totalFightNum);// 挑战N场 更新主线任务,成就,日常任务的进度
        RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_28, totalFightNum);

        return response;
    }

    // CMD_GAME_FIGHT_SNATCH_RANK_LIST = 71033;// 物资争夺 发布悬赏时用的排名悬赏列表
    public static Object CMD_GAME_FIGHT_SNATCH_RANK_LIST(RequestParam clientParam) throws Exception {
        CSGameFightSnatchRankListRequest request = CSGameFightSnatchRankListRequest.parseFrom(clientParam.getData());
        CSGameFightSnatchRankListResponse.Builder response = CSGameFightSnatchRankListResponse.newBuilder();
        long userId = clientParam.getUserId();

        if (!FightManager.checkSnatchMoudleOpen()) {
            return ErrorWord.WRONG_STATUS;//  模块未解锁
        }

        UserInfo userInfo =  GameUser.getUserInfo(userId);
        int serverId = userInfo.getServerId();

        int rankType = RankConstant.SERVER_RANK_SNATCH;
        String dateKey = RankManager.getDateKey(rankType);//这周一的0点0分0秒的时间戳
        String rankName = RankManager.getRankName(rankType, serverId, dateKey);
        boolean withScore = false;// 带分数返回的是[id1,score1,id2,score2]）
        JsonArray list = Future.await(RedisTools.getRankListByIndex(rankName, 0, AllParam.RANK_MEMBER_LIST_MAX - 1, withScore));
        for (int i = 0; i < list.size(); i++) {// userid,分数,userid,分数
            long uid = Long.parseLong(list.getString(i));
            response.addRank(GameUser.takeUserDetailInfoBuilder(uid));
        }

        return response;
    }
}




